/* 
 * 
 * Created on 11 Nov 2011 by simonk
 * 
 * Copyright: Multicom Products Ltd. 2011 Bristol, England
 */
package filesystem;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import objects.ObjectCodes;
import objects.shared.Message;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
 *
 * @author simonk
 */
public class FileSystem {
	private Map<Long,CFile> filesMap;
	private LinkedList<Long> freePositions;
	private long fileCount;
	private final long root;
	
	public FileSystem() {
		this.filesMap = new HashMap<Long, CFile> ();
		this.freePositions = new LinkedList<Long>();
		this.fileCount = 1;
		this.root = 0;
		filesMap.put(root,new CFile(root,-1,"Home","0MB",new Date().toString(), true));
	}

	public Map<Long,CFile> getFilesMap() {
		return filesMap;
	}

	public void setFilesMap(Map<Long,CFile> filesMap) {
		this.filesMap = filesMap;
	}

	public long getFileCount() {
		return fileCount;
	}

	public void setFileCount(long fileCount) {
		this.fileCount = fileCount;
	}
	
	public void addFileToRoot(CFile file) {
		addFile(root,file);
	}
	
	public void addFile(long parent, CFile file) {
		file.setId(freePositions.isEmpty() ? fileCount++ : freePositions.poll());
		file.setParent(parent);
		filesMap.put(file.getId(), file);
		if(filesMap.get(parent) != null) {
			filesMap.get(parent).addChild(file);
		}
	}
	
	public void removeFile(CFile file) {
		freePositions.addLast(file.getId());
		filesMap.remove(file.getId());
		filesMap.get(file.getParent()).removeChild(file);
		for(long id : file.getChildren()) {
			removeFile(filesMap.get(id));
		}
	}
	
	public String toString()
	{
		return ObjectCodes.FS+"|"+toJson();
	}
	
	public String toJson()
	{
		return new Gson().toJson(filesMap.values(),new TypeToken<ArrayList<CFile>>() {}.getType());
	}
	
	public static FileSystem fromJson(String json)
	{
		FileSystem fs = new FileSystem();
		Collection<CFile> files = new Gson().fromJson(json, new TypeToken<ArrayList<CFile>>() {}.getType());
		for(CFile file : files) {
			if(file.getId() == 0) {
				continue;
			}
			fs.filesMap.put(file.getId(), file);
		}
		return fs;
	}
}
